package hotel.controller.customer;

import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Pos;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;

import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.util.Callback;

import java.io.IOException;
import java.util.List;

import org.nutz.dao.QueryResult;
import org.nutz.dao.pager.Pager;

import hotel.common.Comm;
import hotel.common.MsgBox;
import hotel.dao.HotelDao;
import hotel.modal.Customer;
import javafx.beans.binding.Bindings;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.control.Label;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableView;

import javafx.scene.control.ChoiceBox;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableRow;

public class CustomerManageController {
	@FXML
	private TableView<Customer> tableView;
	@FXML
	private TableColumn<Customer, Integer> customerNoCol;
	@FXML
	private TableColumn<Customer, String> nameCol;
	@FXML
	private TableColumn<Customer, String> genderCol;
	@FXML
	private TableColumn<Customer, String> certIdCol;
	@FXML
	private TableColumn<Customer, String> phoneCol;
	@FXML
	private TableColumn<Customer, String> typeCol;
	@FXML
	private TableColumn<Customer, Number> discountCol;
	@FXML
	private TableColumn<Customer, Number> creditCol;
	@FXML
	private Button btnTrailerPage;
	@FXML
	private Button btnHomePage;
	@FXML
	private ChoiceBox<String> condCh;
	@FXML
	private TextField condField;
	@FXML
	private Button btnQuery;
	@FXML
	private Button btnAdd;
	@FXML
	private Button btnPrevPage;
	@FXML
	private Button btnNextPage;
	@FXML
	private TextField pageField;
	@FXML
	private Label pageCountLabel;
	
	Pager pager = null;
	boolean condSearchMode = false;
	String col = null;
	String cond = null;
	
	@FXML
	public void initialize() {
		initComponent();
		loadData();
	}
	
	protected void loadData() {
		showList(1);
	}
	
	private void showList(int pageNumber) {
		condSearchMode = false;
		ObservableList<Customer> data = tableView.getItems();
		QueryResult qrs = HotelDao.getCustomerList(pageNumber, 500);
		List<Customer> list = qrs.getList(Customer.class); 	// 获取结果集
		pager = qrs.getPager(); 							// 获取分页信息
		showPagerInfo();
		data.setAll(list);
		tableView.refresh();
	}
	
	private void showPagerInfo() {
		if(pager == null) return ; 
		pageCountLabel.setText("共 " + pager.getPageCount() + " 页");
		pageField.setText(String.valueOf(pager.getPageNumber()));
		btnPrevPage.setDisable(pager.getPageNumber() <= 1);
		btnNextPage.setDisable(pager.getPageCount() == pager.getPageNumber());
		btnHomePage.setDisable(pager.getPageNumber() == 1);
		btnTrailerPage.setDisable(pager.getPageCount() == pager.getPageNumber());
	}
		
	private void condSearch(int pageNumber) {
		condSearchMode = true;
		col = condCh.getSelectionModel().getSelectedItem();
		cond = condField.getText();
		ObservableList<Customer> data = tableView.getItems();
		QueryResult qrs = HotelDao.getCustomerCondSearch(col, cond, pageNumber, 500);
		List<Customer> list = qrs.getList(Customer.class); // 获取结果集
		pager = qrs.getPager(); // 获取分页信息
		showPagerInfo();
		data.setAll(list);
		tableView.refresh();
	}
	
	// Event Listener on Button[#btnQuery].onAction
	@FXML
	public void onBtnQueryAction(ActionEvent event) {
		condSearch(1);
	}
	
	// Event Listener on Button[#btnAdd].onAction
	@FXML
	public void onBtnAddAction(ActionEvent event) {
		Customer customer = new Customer();
		itemAction(customer, 2);
	}

	// Event Listener on Button[#btnTrailerPage].onAction
	@FXML
	public void onBtnTrailerPageAction(ActionEvent event) {
		if (condSearchMode)
			condSearch(pager.getPageCount());
		else
			showList(pager.getPageCount());
	}

	// Event Listener on Button[#btnPrevPage].onAction
	@FXML
	public void onBtnPrevPageAction(ActionEvent event) {
		int page = pager.getPageNumber() - 1;
		if (condSearchMode)
			condSearch(page);
		else
			showList(page);
	}

	// Event Listener on Button[#btnNextPage].onAction
	@FXML
	public void onBtnNextPageAction(ActionEvent event) {
		int page = pager.getPageNumber() + 1;
		if (condSearchMode)
			condSearch(page);
		else
			showList(page);
	}

	// Event Listener on Button[#btnHomePage].onAction
	@FXML
	public void onBtnHomePageAction(ActionEvent event) {
		if (condSearchMode)
			condSearch(1);
		else
			showList(1);
	}
	
	public void initComponent() {
		nameCol.setCellFactory(getStringCallback());
		
		certIdCol.setCellFactory(getStringCallback());
		phoneCol.setCellFactory(getStringCallback());
		typeCol.setCellFactory(getStringCallback());
		customerNoCol.setCellFactory(getIntegerCallback());
		discountCol.setCellFactory(getNumberCallback());
		creditCol.setCellFactory(getNumberCallback());
		genderCol.setCellFactory(col -> new TableCell<Customer, String>() {
			@Override
			protected void updateItem(String item, boolean empty) {
				super.updateItem(item, empty);
				if (empty == true)
					setText(null);
				else if(item.equals("M"))
					setText("男");
				else if(item.equals("F"))
					setText("女");
				setAlignment(Pos.CENTER);
			}
		});
		
		// 监听搜索框enter键按下
		condField.setOnKeyPressed(new EventHandler<KeyEvent>() {
			@Override
			public void handle(KeyEvent ke) {
				if (ke.getCode().equals(KeyCode.ENTER)) {
					condSearch(1);
				}
			}
		});
		
		// 监听显示页数框Enter键按下
		pageField.setOnKeyPressed(new EventHandler<KeyEvent>() {
			@Override
			public void handle(KeyEvent ke) {
				if (ke.getCode().equals(KeyCode.ENTER)) {
					int page = Integer.valueOf(pageField.getText());
					if(condSearchMode) condSearch(page);
					else showList(page);
				}
			}
		});

		pageField.setTextFormatter(Comm.getIntFormatter(1)); // 设置只能输入数字
		
		tableView.setRowFactory(getTableViewCallback()); // 设置右键菜单
	}
	
	private void itemAction(Customer customer, int mode) {
		FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/hotel/view/customer/CustomerChange.fxml"));
		try {
			Parent root = (Parent) fxmlLoader.load();
			CustomerChangeController controller = fxmlLoader.<CustomerChangeController>getController();
			controller.setMode(mode);
			controller.setCustomer(customer); // 向子窗口传递数据
			Stage stage = new Stage();
			stage.setScene(new Scene(root));
			if(mode == 0) stage.setTitle("客户信息修改");
			else if(mode == 1) stage.setTitle("客户信息详情");
			else if(mode == 2) stage.setTitle("新增客户");
			else return ;
			stage.setResizable(false);
			stage.initModality(Modality.APPLICATION_MODAL);
			stage.showAndWait(); // 显示窗口并等待用户操作
			if(customer.isModified()) {
				if(mode == 0) {
					if (!HotelDao.update(customer)) {
						MsgBox.showErrorDialog("错误", "客户信息修改失败！", "没有成功写入数据库！");
					}
				}else if(mode == 2) {
					if(!HotelDao.add(customer)) {
						MsgBox.showErrorDialog("错误", "客户信息添加失败！", "没有成功写入数据库！");
					}
				}
				tableView.refresh(); // 刷新表格
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	private Callback<TableView<Customer>, TableRow<Customer>> getTableViewCallback() {
		return new Callback<TableView<Customer>, TableRow<Customer>>() {
			@Override
			public TableRow<Customer> call(TableView<Customer> param) {
				final TableRow<Customer> row = new TableRow<>();

				final ContextMenu rowMenu = new ContextMenu();
				final MenuItem detailItem = new MenuItem("查看");
				final MenuItem changeItem = new MenuItem("更改");
				final MenuItem deleteItem = new MenuItem("删除");
				
				rowMenu.getItems().addAll(detailItem, changeItem, deleteItem);
				
				detailItem.setOnAction(new EventHandler<ActionEvent>() {
					@Override
					public void handle(ActionEvent event) {
						itemAction(row.getItem(), 1); // 查看
					}
				});
				
				changeItem.setOnAction(new EventHandler<ActionEvent>() {
					@Override
					public void handle(ActionEvent event) {
						itemAction(row.getItem(), 0); // 修改
					}
				});
				
				deleteItem.setOnAction(new EventHandler<ActionEvent>() {
					@Override
					public void handle(ActionEvent event) {
						if(MsgBox.showConfirmationDialog("警告", null, "你确定要删除该客户信息吗？")) {
							Customer customer = row.getItem();
							if(HotelDao.delete(customer)) {	// 删除
								tableView.getItems().remove(customer);
								tableView.refresh();
							}else {
								MsgBox.showErrorDialog("错误", null, "没有成功写入数据库！");
							}
						}
					}
				});
				
				// 鼠标双击查看
				row.setOnMouseClicked(event -> { 
					if (event.getClickCount() == 2 && (!row.isEmpty())) {
						itemAction(row.getItem(), 1);
					}
				});
				
				// only display context menu for non-null items:
				row.contextMenuProperty().bind(Bindings.when(Bindings.isNotNull(row.itemProperty())).then(rowMenu)
						.otherwise((ContextMenu) null));
				return row;
			}
		};
	}
	
	private Callback<TableColumn<Customer, String>, TableCell<Customer, String>> getStringCallback() {
		return new Callback<TableColumn<Customer, String>, TableCell<Customer, String>>() {
			@Override
			public TableCell<Customer, String> call(TableColumn<Customer, String> arg0) {
				return new TableCell<Customer, String>() {
					@Override
					protected void updateItem(String item, boolean empty) {
						super.updateItem(item, empty);
						if (empty == true)
							setText(null);
						else
							setText(item);
						setAlignment(Pos.CENTER);
					};
				};
			}
		};
	}
	
	private Callback<TableColumn<Customer, Integer>, TableCell<Customer, Integer>> getIntegerCallback() {
		return new Callback<TableColumn<Customer, Integer>, TableCell<Customer, Integer>>() {
			@Override
			public TableCell<Customer, Integer> call(TableColumn<Customer, Integer> arg0) {
				return new TableCell<Customer, Integer>() {
					@Override
					protected void updateItem(Integer item, boolean empty) {
						super.updateItem(item, empty);
						if (empty == true)
							setText(null);
						else
							setText(item.toString());
						setAlignment(Pos.CENTER);
					};
				};
			}
		};
	}
	
	private Callback<TableColumn<Customer, Number>, TableCell<Customer, Number>> getNumberCallback() {
		return new Callback<TableColumn<Customer, Number>, TableCell<Customer, Number>>() {
			@Override
			public TableCell<Customer, Number> call(TableColumn<Customer, Number> arg0) {
				return new TableCell<Customer, Number>() {
					@Override
					protected void updateItem(Number item, boolean empty) {
						super.updateItem(item, empty);
						if (empty == true)
							setText(null);
						else
							setText(String.format("%.2f", item));
						setAlignment(Pos.CENTER);
					};
				};
			}
		};
	}
	
	// end
}
